package com.king.pages.novel;

import java.util.Map;

import org.kordamp.ikonli.feather.Feather;
import org.kordamp.ikonli.javafx.FontIcon;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;

import com.king.App;
import com.king.SpringInitOk;
import com.king.components.pagination.KingPagination;
import com.king.event.FormDialogEvent;
import com.king.event.NotificationEvent;
import com.king.pages.novel.entity.Novel;
import com.king.pages.novel.form.NovalEditForm;
import com.king.pages.novel.form.NovelForm;
import com.king.pages.novel.service.NovelService;
import com.king.util.Async;
import com.king.util.LoadFXML;

import atlantafx.base.theme.Styles;
import ch.qos.logback.core.util.StringUtil;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Pagination;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.scene.control.Tooltip;
import javafx.scene.image.Image;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import lombok.extern.slf4j.Slf4j;
import net.rgielen.fxweaver.core.FxControllerAndView;
import net.rgielen.fxweaver.core.FxWeaver;
import net.rgielen.fxweaver.core.FxmlView;

/**
 * 小说-分页页
 *
 * @author king
 * @date 2025年6月23日-15:20:34
 */
@Slf4j
@FxmlView
@Component
public class NovelPage {

	@Autowired
	private NovelService novelService;

	@Autowired
	private SpringInitOk app;

	@FXML
	private VBox box;

	/**
	 * 表格数据源
	 */
	private ObservableList<Map<String, Object>> data;

	@FXML
	private TableView<Map<String, Object>> table;

	@FXML
	private Pagination pagination;

	@FXML
	private TableColumn<Map<String, Object>, Integer> indexT;
	@FXML
	private TableColumn<Map<String, Object>, Object> nameT;
	@FXML
	private TableColumn<Map<String, Object>, Object> writerT;
	@FXML
	private TableColumn<Map<String, Object>, Object> volumeNumT;
	@FXML
	private TableColumn<Map<String, Object>, Object> chapterNumT;
	@FXML
	private TableColumn<Map<String, Object>, Object> descriptionT;
	@FXML
	private TableColumn<Map<String, Object>, Object> statusT;
	@FXML
	private TableColumn<Map<String, Object>, Object> createDateT;

	private KingPagination kingPagination;

	@Autowired
	private FxWeaver fxWeaver;

	@Autowired
	LoadFXML loadFXML;

	@Autowired
	private ApplicationEventPublisher publisher;

	/**
	 * 查询条件
	 */
	private Novel search;

	@Autowired
	private Async async;

	/**
	 * 当前选中的书
	 */
	private Novel selNovel;

	/**
	 * FXML初始化完成后，回调函数
	 * 
	 * @author king
	 * @date 2025年6月24日-11:09:05
	 */
	@FXML
	private void initialize() {
		search = new Novel();
		data = FXCollections.observableArrayList();
		// 字段绑值
		// index是一个特殊字段，数据不用从数据库查询，直接递增即可
		indexT.setCellValueFactory(d -> {
			int index = data.indexOf(d.getValue()) + 1;
			return new SimpleObjectProperty<>(index);
		});
		nameT.setCellValueFactory(d -> new SimpleObjectProperty<>(d.getValue().get("name")));
		writerT.setCellValueFactory(d -> new SimpleObjectProperty<>(d.getValue().get("writer")));
		volumeNumT.setCellValueFactory(d -> new SimpleObjectProperty<>(d.getValue().get("volumeNum")));
		chapterNumT.setCellValueFactory(d -> new SimpleObjectProperty<>(d.getValue().get("chapterNum")));
		descriptionT.setCellValueFactory(d -> new SimpleObjectProperty<>(d.getValue().get("description")));
		statusT.setCellValueFactory(d -> new SimpleObjectProperty<>(d.getValue().get("status")));
		createDateT.setCellValueFactory(d -> new SimpleObjectProperty<>(d.getValue().get("createDate")));

		// 有一些特殊字段，如状态，数据库返回的是：0,1表格中，我们要显示成图标
		statusT.setCellFactory(_ -> new TableCell<>() {
			@Override
			protected void updateItem(Object item, boolean empty) {
				super.updateItem(item, empty);
				// 这里说明一下，为何当empty是null时要将text和graphic设置null，如果不设置null，那么当我们清空表格数据时，那么这里就不会处理，那么将会继续残留原本的UI
				if (!empty) {
					setText(null);// 不显示文本
					FontIcon icon;
					if (item.equals(1)) {
						// 当值是1，启用状态，显示一个绿色√
						icon = FontIcon.of(Feather.CHECK);
						icon.getStyleClass().add(Styles.SUCCESS);
					} else {
						icon = FontIcon.of(Feather.X);
						// 红色的X
						icon.getStyleClass().add(Styles.DANGER);
					}
					setGraphic(icon);
				} else {
					setText(null);
					setGraphic(null);
				}
			}
		});

		// 编辑时间，加一个时间的图标
		createDateT.setCellFactory(_ -> new TableCell<>() {
			@Override
			protected void updateItem(Object item, boolean empty) {
				super.updateItem(item, empty);
				if (!empty) {
					setGraphic(FontIcon.of(Feather.CLOCK));
					setText((String) item);
				} else {
					setText(null);
					setGraphic(null);
				}
			}
		});

		descriptionT.setCellFactory(_ -> new TableCell<>() {
			@Override
			protected void updateItem(Object item, boolean empty) {
				super.updateItem(item, empty);
				if (!empty) {
					String c = (String) item;
					if (c.length() > 20) {
						setText(c.substring(0, 20) + "...");
						Tooltip tip = new Tooltip(c);
						tip.setWrapText(true);
						tip.setMaxWidth(300);
						setTooltip(tip);
					} else {
						setText(c);
					}
				} else {
					setText(null);
					setGraphic(null);
				}
			}
		});

		table.setRowFactory(_ -> {
			TableRow<Map<String, Object>> row = new TableRow<>();
			row.setOnMouseClicked(e -> {
				if (!row.isEmpty()) {
					if (e.getClickCount() >= 2 && !row.isEmpty()) {
						loadBookData((String) row.getItem().get("id"));
					}
					if (selNovel == null) {
						selNovel = new Novel();
					}
					selNovel.setId((String) row.getItem().get("id"));
					selNovel.setName((String) row.getItem().get("name"));
					selNovel.setStatus(Integer.valueOf(row.getItem().get("status").toString()));
				}
			});
			return row;
		});

		// 添加一个测试的数据
		table.setItems(data);
		table.setPlaceholder(new Region());

		// 加载分页器
		FxControllerAndView<KingPagination, HBox> pagination = fxWeaver.load(KingPagination.class);
		kingPagination = pagination.getController();
		pagination.getView().ifPresent(a -> {
			box.getChildren().add(a);
		});
		// 设置切换分页，切换每页显示数量时触发回调
		kingPagination.go(search, () -> {
			// 使用异步线程来处理后台数据，将UI线程和数据分离开
			loadPageData();
		});
	}

	@FXML
	private void onRefresh() {
		this.selNovel = null;
		loadPageData();
	}

	/**
	 * 加载分页数据
	 * 
	 * @author king
	 * @date 2025年7月23日-13:54:59
	 */
	private void loadPageData() {
		async.done(() -> {
			return novelService.selNovelPage(search);
		}, (d) -> {
			data.clear();
			data.addAll(d);
			kingPagination.setTotalSize(search.getRows());
		});
	}

	/**
	 * 加载书的数据
	 * 
	 * @param bookId
	 * @author king
	 * @date 2025年7月4日-16:39:37
	 */
	private void loadBookData(String bookId) {
		FxControllerAndView<NovelForm, Node> ctrl = loadFXML.load(NovelForm.class);
		ctrl.getController().loadData(bookId);
		ctrl.getView().ifPresent((view) -> {
			publisher.publishEvent(FormDialogEvent.build((Region) view, -1, true));
		});
	}

	@FXML
	private void addBook() {
		doneBook(null);
	}

	@FXML
	private void editBook() {
		if (selNovel == null || StringUtil.isNullOrEmpty(selNovel.getId())) {
			publisher.publishEvent(NotificationEvent.build("请先选择一本要编辑的书").autoClose(true));
			return;
		}
		doneBook(selNovel.getId());
	}

	/**
	 * 处理书的数据，添加|编辑
	 * 
	 * @param novelId
	 * @author king
	 * @date 2025年7月23日-13:48:11
	 */
	private void doneBook(String novelId) {
		FxControllerAndView<NovalEditForm, Node> ctrl = loadFXML.loadAndCache(NovalEditForm.class);
		NovalEditForm c = ctrl.getController();
		if (StringUtil.isNullOrEmpty(novelId)) {
			c.resetForm();
		}
		c.loadData(novelId, (_) -> {
			loadPageData();
		});
		ctrl.getView().ifPresent((v) -> {
			publisher.publishEvent(FormDialogEvent.build((VBox) v, .8, true));
		});
	}

	@FXML
	private void deleteBook() {
		if (selNovel == null || StringUtil.isNullOrEmpty(selNovel.getId())) {
			publisher.publishEvent(NotificationEvent.build("请先选择一本要编辑的书").autoClose(true));
			return;
		}
		String msg = "确定-%s-《%s》 这本书吗？";
		msg = String.format(msg, selNovel.getStatus() == 0 ? "启用" : "禁用", selNovel.getName());
		Alert alert = new Alert(AlertType.CONFIRMATION, msg, ButtonType.OK, ButtonType.CANCEL);
		alert.initOwner(app.getStage());
		((Stage) alert.getDialogPane().getScene().getWindow()).getIcons()
				.add(new Image(getClass().getResourceAsStream(App.ICON)));
		alert.setTitle(selNovel.getStatus() == 0 ? "启用" : "禁用");
		Button ok = (Button) alert.getDialogPane().lookupButton(ButtonType.OK);
		Button cancel = (Button) alert.getDialogPane().lookupButton(ButtonType.CANCEL);
		alert.setHeaderText("操作确认！");
		ok.getStyleClass().addAll(Styles.FLAT, Styles.ACCENT);
		ok.setGraphic(FontIcon.of(Feather.SAVE));
		cancel.getStyleClass().addAll(Styles.FLAT, Styles.DANGER);
		cancel.setGraphic(FontIcon.of(Feather.X_SQUARE));
		alert.showAndWait().ifPresent((d) -> {
			if (d.equals(ButtonType.OK)) {
				async.done(() -> {
					return novelService.enableNovel(selNovel);
				}, (data) -> {
					if (data) {
						loadPageData();
						publisher.publishEvent(NotificationEvent.build("操作执行成功！").autoClose(true));
					}
				});
			}
		});
	}

}
